(function(window){
  function ajax(obj){
    if(obj.async === undefined){
      obj.async = true;
    }
    const xhr = new XMLHttpRequest();
    if(!obj.method){
      obj.method = "GET";
    }
    let param = '';
    for(key in obj.data){
      if(param == ''){
        param += `${key}=${obj.data[key]}`
      }else{
        param += `&${key}=${obj.data[key]}`
      }
    }
    var url = obj.url;
    if(obj.method.toLowerCase()==='get'){
      url += param;
    }
    xhr.open(obj.method,url,obj.async);
    setHeaders(obj);
    if(obj.method.toLowerCase()==='get'){
      xhr.send();
    }else{
      xhr.send(param)
    }
    if(obj.async){
      xhr.onload = () => {
        if(xhr.status === 200){
          if(obj.success){
            obj.success(JSON.parse(xhr.responseText));
          }
        }else{
          if(obj.fail){
            obj.fail(xhr.status);
          }
          new Error(xhr.statusText);
        }
      }
      xhr.onerror = () => {
        if(obj.fail){
          obj.fail(xhr.status);
        }
        new Error(xhr.statusText);
      }
    }else{
      if(xhr.readyState === 4){
        if(xhr.status === 200){
          if(obj.success){
            obj.success(JSON.parse(xhr.responseText));
          }
        }else{
          if(obj.fail){
            obj.fail(xhr.status);
          }
          new Error(xhr.statusText);
        }
      }else{
        if(obj.fail){
          obj.fail(xhr.readyState);
        }
        new Error(xhr.readyState);
      }
    }
    function setHeaders(obj){
      for(head in obj.headers){
        xhr.setRequestHeader(head, obj.headers[head]);
      }
    }
  }

  function instance(obj){
    return ajax(obj)
  }

  window.$ajax = instance;
})(window)